#include "Entry_impl.h"
#include "Variant.h"
#include "Cell_impl.h"
#include "Sheet_impl.h"

EntryImpl::EntryImpl(SheetImpl* sheet, const char* memdata, int size)
	: m_sheet(sheet)
	, m_isLoaded(false)
{
	m_cells.clear();
	if(ParseEntryData(memdata, size))
	{
		//do something.
		m_isLoaded = true;
	}
	else
	{
		m_isLoaded = false;
	}
}

EntryImpl::~EntryImpl()
{

	for(int i = 0; i != m_cells.size(); i++)
	{
		Cell* cell = m_cells[i];
		delete cell;
	}
	m_cells.clear();
}

Cell* EntryImpl::GetCell(int column)
{
	if(column <0 || column >= GetSheet()->GetColumnCount())
		return 0;
	return m_cells[column];
}
Cell* EntryImpl::GetCell(const char* title)
{
	int column = GetSheet()->GetColumn(title);
	if(column == -1)
		return 0;
	return m_cells[column];
}
Sheet*	EntryImpl::GetSheet()
{
	return m_sheet;
}
int	EntryImpl::GetID()
{
	if(!GetIDCell())
		return -1;
	return GetIDCell()->toInt();
}
Cell* EntryImpl::GetIDCell()
{
	int idColumn = GetSheet()->GetIDColumn();
	if(idColumn == -1)
		return 0;
	return m_cells[idColumn];
}

bool EntryImpl::IsLoaded()
{
	return m_isLoaded;
}

bool EntryImpl::ParseEntryData(const char* memdata, int size)
{
	int cur = 0;
	int dbeg = 0;
	int column = 0;

	while(cur <= size)
	{
		//ignore blanks
		while(memdata[cur] != ' ' && memdata[cur] != '\t')
		{
			cur++;
			if(cur > size)
				break;
		}
		if(cur != dbeg)
		{
			ParseEntryCell(column++, memdata+dbeg, cur - dbeg);
			//filter blanks
			while((memdata[cur] == ' ' || memdata[cur] == '\t')
				&& size >= cur)
				cur++;

			if(size < cur)
			{
				break;
			}
			else
			{
				dbeg = cur;
			}
		}
	}
	if(m_cells.size() != GetSheet()->GetColumnCount())
		return false;
	else
		return true;
}
bool EntryImpl::ParseEntryCell(int column, const char* memdata, int size)
{
	
	int type = GetSheet()->GetType(column);
	std::string value = std::string(memdata, memdata+size);
	Variant v;
	switch(type)
	{
	case CT_ID:
	case CT_INT:
		v = atoi(value.c_str());
		break;
	case CT_FLOAT:
		v = (float)atof(value.c_str());
		break;
	case CT_STR:
		v = value.c_str();
		break;
	}
	
	CellImpl* cell = new CellImpl(this, v);
	m_cells.push_back(cell);
	return true;
	
	return false;
}

CellIter* EntryImpl::GetFirst()
{
	return new CellIterImpl(m_cells.begin(), m_cells.end());
}

CellIter* EntryImpl::GetLast()
{
	return new CellIterImpl(m_cells.end());
}

int EntryImpl::GetColumn( CellImpl* cell )
{
	int cc = GetSheet()->GetColumnCount();
	for(int i = 0; i != cc; i++)
	{
		if(m_cells[i] == cell)
			return i;
	}
	return 0;
}

